package file;

import pri.file.FOperator;
import common.Constant;
import common.Singleton;
import view.Main;
import vo.Attr;

import java.io.*;
import java.util.Iterator;

public class CfgOperator {

    public boolean config_recreate = false;
    private Main main;

    private static CfgOperator cfgOperator;
    private CfgOperator() {}
    public static CfgOperator getOperator() {
        if(cfgOperator == null) {
            cfgOperator = new CfgOperator();
            cfgOperator.main = Singleton.main();
        }
        return cfgOperator;
    }

    /**
     * 读取或创建配置文件
     */
    public void readConfiguration() {
        String path = Singleton.fUtil().getConfigPath();
        File file = new File(path + "/" + Constant.CONFIG);
        try {// 如果文件不存在创建文件
            String content;
            if (!file.exists())
                content = createConfiguration(new File(path), file);
            else {// 存在文件则提取文件
                content = FOperator.read(file, "UTF-8", 100000);
                if (content.charAt(0) == '¤') {
                    content = content.substring(1);
                } else {
                    file.delete();
                    content = createConfiguration(new File(path), file);
                }
            }
            String[] cfgs = content.split("/");
            String[] lines = cfgs[0].split("；");
            // 属性
            int index = 1;
            main.attrsName = new String[lines.length];// 添加名字
            for (String line : lines) main.pointed_attrs.add(readCfgLine(line, index++));
            // 其他配置
            String[] other = cfgs[1].split("；");
            for (String anOther : other) {
                String[] os = anOther.split("：");
                switch (os[0]) {
                    case "sz":
                        main.presentFontSize = main.recordFontSize = Integer.parseInt(os[1]);
                        break; // 字体大小
                    case "dl":
                        main.setSpliterDivideLocRecord(Integer.parseInt(os[1]));
                        break; // 分隔符位置
                    case "sl":
                        main.recordAttrShowerLoc = Integer.parseInt(os[1]);
                        break; // shower位置
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String createConfiguration(File path, File file) throws IOException {
        String content;
        path.mkdirs();// 创建目录
        file.createNewFile();// 创建文件
        InputStream is = Singleton.resource().configInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is, Constant.Encode));
        content = br.readLine().substring(1);
        FOperator.write(file, content, "UTF-8");
        content = content.substring(1);
        return content;
    }

    private Attr readCfgLine(String line, int type_index) {
        boolean normal = line.charAt(0) != '#';// 开头为此标记为目录行
        if (normal) {
            String[] ss = line.split("：");
            Attr attr = new Attr(ss[0], type_index);
            main.attrsName[type_index - 1] = ss[0];
            if (ss.length == 2) {
                String[] sss = ss[1].split("、");
                for (String ss1 : sss) {
                    attr.addNew(ss1, false);
                }
            } else if (ss.length > 2)
                System.err.println("Unthoughtable Exception in XFile.readCfgLine(String line,int type_index)");
            return attr;
        }
        main.attrsName[type_index - 1] = line.split("：")[0].substring(1);
        return readFolderLine(line, type_index);
    }

    private Attr readFolderLine(String line, int type_index) {
        Attr attr = null, pre = null;
        String temp = "";
        for (int i = 1; i < line.length(); i++) {
            switch (line.charAt(i)) {
                case '：':// 此时对于根目录是新建，对于副目录是设置文本
                    if (attr == null)
                        attr = pre = new Attr(temp, type_index);
                    else {
                        assert pre != null;
                        pre.setText(temp);
                    }
                    temp = "";
                    break;
                case '【':// 添加并进入下一级目录
                    Attr temp_attr = new Attr(type_index);
                    if (pre != null) {
                        pre.addFolder(temp_attr, false);
                    }
                    pre = temp_attr;
                    temp = "";
                    break;
                case '、':// 添加新的候选项
                    if (pre != null) {
                        pre.addNew(temp, false);
                    }
                    temp = "";
                    break;
                case '】':// 返回上一级目录
                    if (pre == null)
                        break;
                    if (!temp.equals(""))
                        pre.addNew(temp, false);
                    pre = pre.getBoss();
                    temp = "";
                    break;
                default:
                    temp += line.charAt(i);
            }
        }
        if (!temp.equals("") && attr != null)
            attr.addNew(temp, false);
        return attr;
    }

    /**
     * 添加新的候选词后重新设置配置文件
     */
    public void reCreateConfiguration() {
        if (config_recreate) {
            String path = Singleton.fUtil().getConfigPath();
            StringBuilder toWrite = new StringBuilder();
            for (Attr next : main.pointed_attrs) {
                if (next.getFolders().length > 0) {
                    toWrite.append("#").append(next.getText()).append("：");
                    toWrite.append(serializeAttrs(next.getFolders()));// 读取目录
                } else
                    toWrite.append(next.getText()).append("：");
                Iterator<String> is = next.getCandidate().iterator();
                while (is.hasNext()) {
                    toWrite.append(is.next());
                    if (is.hasNext())
                        toWrite.append("、");
                }
                toWrite.append("；");
            }
            toWrite = new StringBuilder(Constant.Config_sign + toWrite + "/sz：" + main.presentFontSize + "；"); // 配置标记和字体大小
            toWrite.append("dl：").append(main.getSpliterDivideLoc()).append("；"); // 分隔符位置
            toWrite.append("sl：").append(main.getShowerLocation()).append("；"); // 属性显示板位置
            FOperator.write(new File(path + "/" + Constant.CONFIG), toWrite.toString(), Constant.Encode);
        }
    }

    /**
     * 序列化属性
     */
    private String serializeAttrs(Attr folders[]) {
        StringBuilder s = new StringBuilder();
        for (Attr folder : folders) {
            s.append("【").append(folder.getText()).append("：");
            s.append(serializeAttrs(folder.getFolders()));
            Iterator<String> is = folder.getCandidate().iterator();
            while (is.hasNext()) {
                s.append(is.next());
                if (is.hasNext())
                    s.append("、");
            }
            s.append("】");
        }
        return s.toString();
    }
}
